﻿<%@ WebHandler Language="C#" Class="ContainerWFChangeHoldReleaseHandler" %>

/*Description: 批次工艺变更冻结释放处理程序
'Copyright (c) : 通力凯顿（北京）系统集成有限公司
'Writer: Zhangrj 
'create Date:20250813
'Rewriter:
'Rewrite Date:
*/
using System;
using System.Web;
using BusinessRule.DTO;
using System.Web.SessionState;
using DatabaseAccess.DBUtility;
using System.Data.OracleClient;
using System.Data;
using Newtonsoft.Json;
using System.Collections.Generic;
using BusinessRule.Business;
using BusinessRule.IBusiness;
using BusinessRule.BusinessFactory;
using System.Text;
using System.Collections;

public class ContainerWFChangeHoldReleaseHandler : IHttpHandler, IRequiresSessionState
{

    CurrentUserInfo m_UserInfo;
    uLMSCommonBusiness commonBusiness = new uLMSCommonBusiness();
    public void ProcessRequest(HttpContext context)
    {
        try
        {
            var action = context.Request["action"].ToString();
            m_UserInfo = (CurrentUserInfo)context.Session["CurrentUserInfo"];
            if (m_UserInfo == null)
            {
                context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Result = false, Message = "登录过期，请重新登录" }));
                return;
            }
            switch (action)
            {
                case "GetContainerWfChangeHoldList": //获取批次工艺变更冻结数据列表
                    GetContainerWfChangeHoldList(context);
                    break;
                case "GetWfChangeReleasePageInitData": //获取工艺变更释放页面初始化数据
                    GetWfChangeReleasePageInitData(context);
                    break;
                case "SaveWfChangeReleaseAuditRecord": //保存工艺变更释放审核数据
                    SaveWfChangeReleaseAuditRecord(context);
                    break;
                case "IsExistAuditRecord": //判断批次是否存在审核申请记录
                    IsExistAuditRecord(context);
                    break;
                default:
                    context.Response.Write(JsonConvert.SerializeObject(new uMESProcessResult() { Result = false, Message = "未知操作" }));
                    break;
            }
        }
        catch (Exception ex)
        {
            uMESProcessResult result = new uMESProcessResult();
            result.Result = false;
            result.Message = ex.Message;
            context.Response.ContentType = "text/html";
            context.Response.Write(JsonConvert.SerializeObject(result));
        }
    }

    /// <summary>
    /// 判断批次是否存在审核申请记录
    /// </summary>
    /// <param name="context"></param>
    private void IsExistAuditRecord(HttpContext context)
    {
        uMESProcessResult result = new uMESProcessResult() { Result = true, Message = "获取成功" };
        string sql1 = "SELECT 1 FROM containerreleaseauditrecord cr WHERE cr.containerid = '{0}' AND cr.status = {1}";
        string containerID = context.Request["containerID"].ToString();
        if (DatabaseHelper.GetSingle(string.Format(sql1, containerID, int.Parse(((Enum)ReleaseAuditStatus.已提交).ToString("D")))) != null)
        {
            result.Result = false; result.Message = "批次已存在申请记录，无法操作！";
        }
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    private enum WfChangeAuditType
    {
        解冻申请 = 1, 审核退回 = 2, 审核通过 = 3
    }

    /// <summary>
    /// 保存工艺变更申请审核记录
    /// </summary>
    /// <param name="context"></param>
    private void SaveWfChangeReleaseAuditRecord(HttpContext context)
    {
        uMESProcessResult result = new uMESProcessResult() { Result = true, Message = "获取成功" };
        DataTable dtPageData = JsonConvert.DeserializeObject<DataTable>(context.Request["dtPageData"].ToString());//页面选择的批次数据
        if (dtPageData.Rows.Count == 0)
        {
            result.Result = false;
            result.Message = "请选择数据！";
            context.Response.Write(JsonConvert.SerializeObject(result));
            return;
        }
        WfChangeAuditType opearType = (WfChangeAuditType)int.Parse(context.Request["opearType"].ToString());//操作类型
        switch (opearType)
        {
            case WfChangeAuditType.解冻申请:
                if (IsWfChangeReleaseAuditor()) //如果当前用户不是审核人，不可操作
                {
                    result.Result = false;
                    result.Message = "审核人员不能提交申请！";
                    break;
                }
                result = SaveWfChangeReleaseAuditRecordByApply(dtPageData);//保存数据
                break;
            case WfChangeAuditType.审核退回:
                if (!IsWfChangeReleaseAuditor()) //如果当前用户不是审核人，不可操作
                {
                    result.Result = false;
                    result.Message = "未获得审核授权！";
                    break;
                }
                string backReason = context.Request["backReason"].ToString();//退回原因
                if (string.IsNullOrWhiteSpace(backReason))
                {
                    result.Result = false;
                    result.Message = "请填写退回原因！";
                    break;
                }
                result = SaveWfChangeReleaseAuditRecordByBack(dtPageData, backReason);//保存数据
                break;
            case WfChangeAuditType.审核通过:
                if (!IsWfChangeReleaseAuditor()) //如果当前用户不是审核人，不可操作
                {
                    result.Result = false;
                    result.Message = "未获得审核授权！";
                    break;
                }
                result = SaveWfChangeReleaseAuditRecordByAudit(dtPageData);//保存数据
                break;
            default:
                result.Result = false;
                result.Message = "未知操作！";
                break;
        }
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 保存申请的工艺变更申请审核记录
    /// </summary>
    /// <param name="dtPageData"></param>
    /// <returns></returns>
    private uMESProcessResult SaveWfChangeReleaseAuditRecordByApply(DataTable dtPageData)
    {
        uMESProcessResult result = new uMESProcessResult() { Result = true, Message = "保存成功" };
        string sql1 = "SELECT 1 FROM containerreleaseauditrecord cr WHERE cr.containerid = '{0}' AND cr.status = {1}";
        string sql2 = "SELECT 1 FROM containerreleaseauditrecord cr WHERE cr.recordid = '{0}' AND cr.status = {1}";
        StringBuilder exSql = new StringBuilder();
        ArrayList sqlList = new ArrayList();
        foreach (DataRow item in dtPageData.Rows)
        {
            if (DatabaseHelper.GetSingle(string.Format(sql1, item["containerid"].ToString(), int.Parse(((Enum)ReleaseAuditStatus.已提交).ToString("D")))) != null)
            {
                result.Result = false;
                result.Message = "已存在申请记录！";
                break;
            }
            if (string.IsNullOrWhiteSpace(item["recordid"].ToString())) //如果为空，则表示未申请记录
            {
                exSql.Append(@"INSERT INTO containerreleaseauditrecord cr(recordid,containerid,applicant,applicationtime,createtime,status) VALUES(");
                exSql.AppendFormat("'{0}',", Guid.NewGuid().ToString());//主键ID
                exSql.AppendFormat("'{0}',", item["containerid"].ToString());//操作记录ID
                exSql.AppendFormat("'{0}',", m_UserInfo.EmployeeID);//申请人
                exSql.Append("SYSDATE,SYSDATE,");//申请时间，创建时间
                exSql.AppendFormat("{0})", int.Parse(((Enum)ReleaseAuditStatus.已提交).ToString("D")));//状态
            }
            else
            { 
                //记录ID不为空，则表示退回重新申请
                if (DatabaseHelper.GetSingle(string.Format(sql2, item["recordid"].ToString(), int.Parse(((Enum)ReleaseAuditStatus.已退回).ToString("D")))) == null)
                {
                    result.Result = false;
                    result.Message = "不存在退回的数据，请重新查询！";
                    break;
                }
                exSql.Append(@"UPDATE containerreleaseauditrecord cr SET cr.backtime = NULL,cr.backreason = '',cr.backauditor = '',");
                exSql.Append(" cr.applicationtime = SYSDATE,");//申请时间
                exSql.AppendFormat("cr.applicant = '{0}',", m_UserInfo.EmployeeID);//申请人
                exSql.AppendFormat("cr.status = {0}", int.Parse(((Enum)ReleaseAuditStatus.已提交).ToString("D")));//状态
                exSql.AppendFormat(" WHERE cr.recordid = '{0}'", item["recordid"].ToString());//操作记录ID
            }
            sqlList.Add(exSql.ToString());
            exSql.Clear();
        }
        if (result.Result)
        {
            DatabaseHelper.ExecuteSqlTran(sqlList);
        }
        return result;
    }

    /// <summary>
    /// 保存退回的工艺变更申请审核记录
    /// </summary>
    /// <param name="dtPageData"></param>
    /// <param name="backReason"></param>
    /// <returns></returns>
    private uMESProcessResult SaveWfChangeReleaseAuditRecordByBack(DataTable dtPageData, string backReason)
    {
        uMESProcessResult result = new uMESProcessResult() { Result = true, Message = "保存成功" };
        string sql = "SELECT 1 FROM containerreleaseauditrecord cr WHERE cr.recordid = '{0}' AND cr.status = {1}";
        StringBuilder exSql = new StringBuilder();
        ArrayList sqlList = new ArrayList();
        foreach (DataRow item in dtPageData.Rows)
        {
            if (DatabaseHelper.GetSingle(string.Format(sql, item["recordid"].ToString(), int.Parse(((Enum)ReleaseAuditStatus.已提交).ToString("D")))) == null)
            {
                result.Result = false;
                result.Message = "不存在申请记录！";
                break;
            }
            exSql.Append(@"UPDATE containerreleaseauditrecord cr SET");
            exSql.Append(" cr.backtime = SYSDATE,");//退回时间
            exSql.AppendFormat("cr.backreason = '{0}',", backReason);//退回原因
            exSql.AppendFormat("cr.backauditor = '{0}',", m_UserInfo.EmployeeID);//退回审核人
            exSql.AppendFormat("cr.status = {0}", int.Parse(((Enum)ReleaseAuditStatus.已退回).ToString("D")));//状态
            exSql.AppendFormat(" WHERE cr.recordid = '{0}'", item["recordid"].ToString());//操作记录ID
            sqlList.Add(exSql.ToString());
            exSql.Clear();
        }
        if (result.Result)
        {
            DatabaseHelper.ExecuteSqlTran(sqlList);
        }
        return result;
    }

    /// <summary>
    /// 保存审核的工艺变更申请审核记录
    /// </summary>
    /// <param name="dtPageData"></param>
    /// <param name="backReason"></param>
    /// <returns></returns>
    private uMESProcessResult SaveWfChangeReleaseAuditRecordByAudit(DataTable dtPageData)
    {
        uMESProcessResult result = new uMESProcessResult() { Result = true, Message = "保存成功" };
        string sql = "SELECT 1 FROM containerreleaseauditrecord cr WHERE cr.recordid = '{0}' AND cr.status = {1}";
        StringBuilder exSql = new StringBuilder();
        ArrayList sqlList = new ArrayList();
        foreach (DataRow item in dtPageData.Rows)
        {
            if (DatabaseHelper.GetSingle(string.Format(sql, item["recordid"].ToString(), int.Parse(((Enum)ReleaseAuditStatus.已提交).ToString("D")))) == null)
            {
                result.Result = false;
                result.Message = "不存在申请记录！";
                break;
            }
            exSql.Append(@"UPDATE containerreleaseauditrecord cr SET");
            exSql.Append(" cr.audittime = SYSDATE,");//审核时间
            exSql.AppendFormat("cr.auditor = '{0}',", m_UserInfo.EmployeeID);//审核人
            exSql.AppendFormat("cr.status = {0}", int.Parse(((Enum)ReleaseAuditStatus.已审核).ToString("D")));//状态
            exSql.AppendFormat(" WHERE cr.recordid = '{0}'", item["recordid"].ToString());//操作记录ID
            sqlList.Add(exSql.ToString());
            sqlList.Add(GetSaveOperConRecordByWfChangeRele(item));
            sqlList.Add(string.Format("UPDATE containercurrentinfo c SET c.ishold = 0 WHERE c.containerid = '{0}'", item["containerid"].ToString()));
            exSql.Clear();
        }
        if (result.Result)
        {
            DatabaseHelper.ExecuteSqlTran(sqlList);
        }
        return result;
    }

    /// <summary>
    /// 获取插入批次释放的SQL
    /// </summary>
    /// <param name="dr"></param>
    /// <returns></returns>
    private string GetSaveOperConRecordByWfChangeRele(DataRow dr)
    {
        StringBuilder sqlBl = new StringBuilder();
        //插入批次释放记录
        sqlBl.Append(@"INSERT INTO OperContainerRecord(containerid,containername,productid,productname,operatorid,operreason,qty,createdate,opertype)
                VALUES(");
        sqlBl.AppendFormat("'{0}',", dr["containerid"].ToString());
        sqlBl.AppendFormat("'{0}',", dr["containername"].ToString());
        sqlBl.AppendFormat("'{0}',", dr["productid"].ToString());
        sqlBl.AppendFormat("'{0}',", dr["productname"].ToString());
        sqlBl.AppendFormat("'{0}',", Guid.NewGuid().ToString());
        sqlBl.AppendFormat("'{0}',", "工艺变更释放");
        sqlBl.AppendFormat("{0},", dr["qty"].ToString());
        sqlBl.Append("SYSDATE, '2')");
        return sqlBl.ToString();
    }

    /// <summary>
    /// 获取工艺变更释放页面初始化数据
    /// </summary>
    /// <param name="context"></param>
    private void GetWfChangeReleasePageInitData(HttpContext context)
    {
        uMESProcessResult result = new uMESProcessResult() { Result = true, Message = "获取成功" };
        Dictionary<string, object> resData = new Dictionary<string, object>();
        /*获取角色类型*/
        resData.Add("RoleTypeName", "申请人");
        resData.Add("StatusDefault", int.Parse(((Enum)ReleaseAuditStatus.未提交).ToString("D")));
        if (IsWfChangeReleaseAuditor())
        {
            resData["RoleTypeName"] = "审核人";
            resData["StatusDefault"] = int.Parse(((Enum)ReleaseAuditStatus.已提交).ToString("D"));
        }
        /*获取状态下拉框值*/
        DataTable dtStatus = new DataTable("dtStatus");
        dtStatus.Columns.Add("key");
        dtStatus.Columns.Add("value");
        foreach (var value in Enum.GetValues(typeof(ReleaseAuditStatus)))
        {
            DataRow dr = dtStatus.NewRow();
            dr["key"] = Enum.GetName(typeof(ReleaseAuditStatus), value);
            dr["value"] = (int)value;
            dtStatus.Rows.Add(dr);
        }
        resData.Add("dtStatus", dtStatus);
        result.ReturnData = resData;
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 当前登录用户是否是工艺变更暂停释放审核人
    /// </summary>
    /// <returns></returns>
    private bool IsWfChangeReleaseAuditor()
    {
        bool res = false;
        string querySql = @"SELECT ci.customobjectitemsname rolename FROM CustomObject C
                            LEFT JOIN customobjectitems ci ON ci.customobjectid = c.customobjectid AND ci.isuse = 0
                            WHERE c.customobjectname = '工艺变更暂停释放审核角色' AND c.isuse = 0";
        DataTable dtDic = DatabaseHelper.Query_ReturnDatTable(querySql);//查出所有的角色
        foreach (DataRow item in dtDic.Rows)
        {
            if (!string.IsNullOrWhiteSpace(item["rolename"].ToString()) && m_UserInfo.Roles.Contains(item["rolename"].ToString()))//如果登录人包含该审核角色，则表示该人员为审核人员
            {
                res = true;
                break;
            }
        }
        return res;
    }

    /// <summary>
    /// 释放审核状态
    /// </summary>
    private enum ReleaseAuditStatus
    {
        未提交 = 0,
        已提交 = 1,
        已退回 = 2,
        已审核 = 3
    }

    /// <summary>
    /// 获取批次工艺变更冻结的数据列表
    /// </summary>
    /// <param name="context"></param>
    public void GetContainerWfChangeHoldList(HttpContext context)
    {
        Dictionary<string, string> dic = JsonConvert.DeserializeObject<Dictionary<string, string>>(context.Request["params"].ToString());//查询参数
        /*查询数据*/
        StringBuilder sql = new StringBuilder();
        switch ((ReleaseAuditStatus)int.Parse(dic["Status"]))
        {
            case ReleaseAuditStatus.未提交:
                sql.AppendFormat(GetContainerWfChangeHoldSQL(), m_UserInfo.FactoryID);
                break;
            default:
                sql.AppendFormat(GetWfChangeReleaseAuditSQL(), dic["Status"], m_UserInfo.FactoryID);
                break;
        }
        if (dic.ContainsKey("MfgOrderName") && !string.IsNullOrWhiteSpace(dic["MfgOrderName"]))
        {
            sql.AppendFormat(" AND c.mfgordername = '{0}'", dic["MfgOrderName"]);
        }
        if (dic.ContainsKey("ProductName") && !string.IsNullOrWhiteSpace(dic["ProductName"]))
        {
            sql.AppendFormat(" AND c.productname LIKE '%{0}%'", dic["ProductName"]);
        }
        if (dic.ContainsKey("ContainerName") && !string.IsNullOrWhiteSpace(dic["ContainerName"]))
        {
            sql.AppendFormat(" AND c.containername LIKE '%{0}%'", dic["ContainerName"]);
        }
        uMESPagingDataDTO pageDto = new uMESPagingDataDTO();
        pageDto.CurrentPageIndex = int.Parse(dic["pageIndex"].ToString());
        pageDto.PageSize = int.Parse(dic["pageSize"].ToString());
        pageDto.strSQL = sql.ToString();
        uMESProcessResult result = DatabaseHelper.RunProcedureForPage(pageDto);
        result.DBTable = GetLastWfChangeHoldList(result.DBTable);
        context.Response.Write(JsonConvert.SerializeObject(result));
    }

    /// <summary>
    /// 获取最终的查询数据
    /// </summary>
    /// <param name="dtData"></param>
    /// <returns></returns>
    private DataTable GetLastWfChangeHoldList(DataTable dtData)
    {
        dtData.Columns.Add("LASTNEWWORKFLOWINFO");
        string sql = @"SELECT wb1.workflowname,ww.workflowid,ww.workflowrevision FROM product p
                          LEFT JOIN workflowbase wb ON wb.workflowbaseid = p.workflowbaseid
                          LEFT JOIN workflow w ON w.workflowid = NVL(wb.revofrcdid,p.workflowid)
                          LEFT JOIN workflowbase wb1 ON wb1.workflowbaseid = w.workflowbaseid
                          LEFT JOIN workflow ww ON ww.workflowbaseid = wb1.workflowbaseid
                          WHERE p.productid = '{0}'
                          ORDER BY ww.workflowid DESC";
        foreach (DataRow item in dtData.Rows)
        {
            DataTable dtNew  = DatabaseHelper.Query_ReturnDatTable(string.Format(sql,item["productid"].ToString()));
            if (dtNew.Rows.Count>0)
            {
                item["LASTNEWWORKFLOWINFO"] = string.Format("{0}:{1}", dtNew.Rows[0]["workflowname"].ToString(), dtNew.Rows[0]["workflowrevision"].ToString());
            } 
        }
        return dtData;
    }

    /// <summary>
    /// 获取可申请的暂停批次SQL
    /// </summary>
    /// <returns></returns>
    private string GetContainerWfChangeHoldSQL()
    {
        return @"SELECT c.containerid,c.containername,c.containertype,DECODE(C.containertype,2,'批量加工',3,'批量带子序号', 7,'单件加工') containertypename,
                            c.mfgordername,c.qty,c.togetherflag,c.isinstore,DECODE(c.isdispatch,1,'是','否') isdispatch,DECODE(c.isship,1,'是','否') isship,
                            DECODE(c.iscommissioning,1,'是','否') iscommissioning, DECODE(c.ishold,1,'是','否') ishold,
                            CASE WHEN NVL(c.splitnum,0) >0 THEN '是' ELSE '否' END issplit,CASE WHEN NVL(c.workreportnum,0) > 0 THEN '是' ELSE '否' END IsWorkReport,
                            c.productid,c.productname,c.productrevision productrev,c.productdescription productdesc,NVL(c.workreportnum,0) workreportnum,
                            c.workflowid,c.workflowname,c.workflowrevision workflowrev,c.workflowname || ':' || c.workflowrevision workflowinfo,
                            c.workflowstepid,c.workflowstepname, oc.createdate holdtime,'' recordid
                            FROM opercontainerrecord oc
                            LEFT JOIN containercurrentinfo c ON c.containerid = oc.containerid
                            INNER JOIN (
                            SELECT MAX(oc2.createdate) createdate,oc2.containerid FROM opercontainerrecord oc2 WHERE oc2.opertype = '2' GROUP BY oc2.containerid)
                            moc ON moc.containerid = oc.containerid AND moc.createdate = oc.createdate --关联批次的最新暂停必须是工艺变更暂停
                            WHERE oc.opertype = '2' AND c.containerstatus = 1 AND c.isinstore != 1 AND c.ishold = 1
                            AND c.originalfactoryid = '{0}' AND oc.operreason = '工艺变更暂停'
                            AND NOT EXISTS(SELECT 1 FROM containerreleaseauditrecord cr WHERE cr.containerid = oc.containerid AND cr.status != 3) --不存在申请记录
                            AND NOT EXISTS(SELECT 1 FROM opercontainerrecord oc1 WHERE oc1.opertype = '3' AND oc1.operreason = '工艺变更释放' AND oc1.containerid = oc.containerid AND oc1.createdate > oc.createdate)";
    }

    /// <summary>
    /// 获取已经申请的工艺变更批次SQL
    /// </summary>
    /// <returns></returns>
    private string GetWfChangeReleaseAuditSQL()
    {
        return @"SELECT c.containerid,c.containername,c.containertype,DECODE(C.containertype,2,'批量加工',3,'批量带子序号', 7,'单件加工') containertypename,
                            c.mfgordername,c.qty,c.togetherflag,c.isinstore,DECODE(c.isdispatch,1,'是','否') isdispatch,DECODE(c.isship,1,'是','否') isship,
                            DECODE(c.iscommissioning,1,'是','否') iscommissioning, DECODE(c.ishold,1,'是','否') ishold,
                            CASE WHEN NVL(c.splitnum,0) >0 THEN '是' ELSE '否' END issplit,CASE WHEN NVL(c.workreportnum,0) > 0 THEN '是' ELSE '否' END IsWorkReport,
                            c.productid,c.productname,c.productrevision productrev,c.productdescription productdesc,NVL(c.workreportnum,0) workreportnum,
                            c.workflowid,c.workflowname,c.workflowrevision workflowrev,c.workflowname || ':' || c.workflowrevision workflowinfo,
                            c.workflowstepid,c.workflowstepname,
                            cr.status,cr.recordid,ea.fullname applicant,ed.fullname auditor,eb.fullname backauditor,
                            cr.applicationtime,cr.audittime,cr.backtime,cr.backreason
                            FROM containerreleaseauditrecord cr
                            LEFT JOIN employee ea ON ea.employeeid = cr.applicant
                            LEFT JOIN employee ed ON ed.employeeid = cr.auditor
                            LEFT JOIN employee eb ON eb.employeeid = cr.backauditor
                            LEFT JOIN containercurrentinfo c ON c.containerid = cr.containerid
                            WHERE cr.status = {0} AND c.containerstatus = 1 AND c.originalfactoryid = '{1}' AND c.isinstore != 1";
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}